package com.leesche.zcsp.node.web.intecepter.APP;

import com.alibaba.fastjson.JSON;
import com.leesche.zcsp.node.app.v1.controller.register.AppRegisterController;
import com.leesche.zcsp.node.app.v1.timer.TokenCacheTimer;
import com.leesche.zcsp.node.utils.web.SessionManager;
import com.leesche.zcsp.node.utils.web.gernerator.TokenGernerator;
import com.leesche.zcsp.node.utils.web.messge.WebResult;
import com.leesche.zcsp.node.web.constants.Constants;
import com.leesche.zcsp.node.web.model.SysUser;
import com.leesche.zcsp.node.web.model.SysUserToken;
import com.leesche.zcsp.node.web.service.SysModuleService;
import com.leesche.zcsp.node.web.service.SysUserService;
import com.leesche.zcsp.node.web.service.SysUserTokenService;
import com.leesche.zcsp.node.web.service.impl.data.read.QuerySysModuleCondition;
import com.leesche.zcsp.node.web.service.impl.data.read.QuerySysUserTokenCondition;
import com.leesche.zcsp.node.web.vo.Principal;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

/**
 * @author Jerry Chan
 * @version V1.0
 * @Title: APPTokenInterceptor.java
 * @Description: TODO(APP令牌校验拦截器)
 * @date 2016年10月21日 下午7:02:40
 */
public class APPTokenInterceptor extends HandlerInterceptorAdapter {

    private static final Logger logger = Logger
            .getLogger(AppRegisterController.class);

    @Autowired
    private SysUserTokenService sysUserTokenService;

    @Autowired
    private SysModuleService sysModuleService;

    @Autowired
    private SysUserService sysUserService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            String token = request.getHeader("User-Token");

            if (token == null || "".equals(token)) {
           /* response.addHeader("description", "TOKEN_IS_NULL");
            response.sendError(403);*/
                getTokenResponse(response);
                return false;
            }


            /**从缓存中读取token 存在则不去数据库中读取**/
            SysUserToken userToken = TokenCacheTimer.getTokenByToken(token);

            if(userToken==null) {
                QuerySysUserTokenCondition condition = new QuerySysUserTokenCondition();
                condition.setToken(token);
                userToken = sysUserTokenService.findUserTokenByCondition(condition);
                //数据中读取的token 存在加入到缓存
                if(userToken!=null) {
                    TokenCacheTimer.addUserToken(token, userToken);
                }
            }
            if (userToken == null) {
              /*  response.addHeader("description", "TOKEN_NOT_FIND");
                response.sendError(401);*/
                getTokenResponse(response);
                return false;
            }
            //当有效时间过期则刷新令牌
            if (userToken.getOuttime().getTime() < new Date().getTime()) {
                getTokenResponse(response);
                TokenCacheTimer.clearToken(userToken.getToken());
                return false;

              /*  //token过期清除
                TokenCacheTimer.clearToken(userToken.getToken());

                TokenGernerator.setupUserToken(userToken, userToken.getUserid());
                if (sysUserTokenService.updateByPrimaryKeySelective(userToken) > 0) {
                    //加入新token
                    TokenCacheTimer.addUserToken(userToken.getToken(),userToken);

                    //根据用户令牌获取用户信息并设置为登录状态
                    //return this.savePrincipalLoginState(userToken);
                    //刷新令牌成功,返回407状态码。并带回用户令牌
                   *//* response.addHeader("description", "TOKEN_UPDATE_SUCCESS");
                    response.addHeader("UserToken",userToken.getToken());
                    response.sendError(407);*//*
                    getTokenResponse(response);

                    return false;
                } else {
                    *//*response.addHeader("description", "TOKEN_UPDATE_ERROR");
                    response.sendError(401);*//*
                    getTokenResponse(response);
                    return false;
                }*/
            }

            return  this.savePrincipalLoginState(userToken,response);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            response.addHeader("description", "SYSTEM_NO_FREE");
            response.sendError(503);
            return false;
        }
        // return true;
    }


    /**
     * @param userToken 用户令牌
     * @return 保存结果
     * @Title: savePrincipalLoginState(SysUserToken userToken)
     * @Description: TODO(保存用户为登录状态)
     * @author Jerry
     * @date 2016-10-19 11:08:20
     */
    private boolean savePrincipalLoginState(SysUserToken userToken,HttpServletResponse response)  throws IOException {
        Principal principal=  TokenCacheTimer.getUserPrincipal(userToken.getToken());
        if(principal!=null){
            return true;
        }
        SysUser loginUser = sysUserService.selectByPrimaryKey(userToken.getUserid());
        if (loginUser != null) {
           String principalName = loginUser.getBusinessno() != null ? loginUser
                    .getBusinessno() : loginUser.getUsername();

            principal = new Principal(loginUser.getUserid(),
                    loginUser.getPuserid(), principalName,
                    loginUser.getBusinessno(), loginUser.getNtype(),
                    loginUser.getOpenid(), userToken.getToken(), Constants.MODULE_TYPE_APP,loginUser.getShortcode());

            QuerySysModuleCondition querySysModuleCondition = new QuerySysModuleCondition();
            querySysModuleCondition.setnType(Constants.MODULE_TYPE_APP);
            querySysModuleCondition.setUserId(principal.getUserid());
            principal.setModuleIds(sysModuleService.findModuleIDbyUserID(querySysModuleCondition));
            //权限不存在，则刷新到缓存中
            TokenCacheTimer.addUserPrincipal(userToken.getToken(),principal);
/*
            SessionManager.setSessionAttribute(Constants.LOGIN_CURRENT_USER, principal);
*/
            return true;
        }

        this.getTokenResponse(response);
        return false;
    }

    private void getTokenResponse(HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        String jsonString = JSON.toJSONString(WebResult.failure("loginDenied").toMap());
        PrintWriter out = response.getWriter();
        out.write(jsonString);
        out.close();
    }
}
